#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <functional>
#include "Socket.hpp"
#include "protocol.hpp"
#include <pthread.h>
#include "Calculate.hpp"
using namespace std;

using task_t = function<string(string& inbufferstream, bool* error_code)>;
class TcpServer;

struct ThreadData {
    ThreadData(TcpServer* tcp_this, net_work::Socket* sockp) 
        :_this(tcp_this)
        ,_sockp(sockp)
    {}
    net_work::Socket* _sockp;
    TcpServer* _this;
};

class TcpServer {
public :
    TcpServer(uint16_t port, task_t handler_request)
        :_port(port)
        ,_listensocket(new net_work::TcpSocket())
        ,_handler_request(handler_request)
    {
        // 创建监听套接字
        _listensocket->BuildListenSocketMethod(_port, net_work::default_backlog);
    }
    static void* ThreadRoutine(void* args) {
        // 将当前线程去关联
        pthread_detach(pthread_self());
        ThreadData* td = static_cast<ThreadData*>(args);

        string inbufferstream;
        while (true) {
            // 读取数据，不关心数据是什么，只读取数据
            // 1、读取报文
            if (!td->_sockp->Recv(&inbufferstream, 1024)) {
                break;
            }
            bool error_code = true;
            string send_string = td->_this->_handler_request(inbufferstream, &error_code); // 处理数据
            if (error_code) {
                if (!send_string.empty()) {
                    // 发送数据，也不关心数据是什么，只发送
                    td->_sockp->Send(send_string);
                } else {
                    break;
                }
            }  
        }


        td->_sockp->CloseSockFd();
        delete td->_sockp;
        delete td;
        return nullptr;
    }
    void Loop() {
        while (true) {
            // 获取连接
            string peerip;
            uint16_t peerport;
            net_work::Socket* newsocket = _listensocket->AcceptSocket(&peerip, &peerport);
            if (!newsocket) {
                // 获取失败，继续下一个
                continue;
            }
            cout << "获取一个新链接, newsockfd: " << newsocket->GetSockFd() << ", clientip: " << peerip << ", clientport: " << peerport << endl;
            // 创建多线程大处理
            pthread_t tid;
            ThreadData* td = new ThreadData(this, newsocket);
            pthread_create(&tid, nullptr, ThreadRoutine, td);
            // newsocket->CloseSockFd();
        }

    }
    ~TcpServer() {

    }
private :
    uint16_t _port;
    net_work::Socket* _listensocket;
    task_t _handler_request;
};

